/* eslint-disable max-params */
/* eslint-disable max-depth */
/* eslint-disable @typescript-eslint/no-this-alias */
import CreateEntity from './classes/CreateEntity';
import { YEvent } from './interface';
import {
  YItemConfig,
  YRule,
  YInterception,
  YForm,
  YMapping,
  FormMapping,
  YItemRow,
  YDictionary,
} from './interface';
import FormUtil from './linkedList/FormUtil';
import Form from './linkedList/FormUtil';
import getYcConfigFormOption, { YOptions, YUIName } from './utils';

interface YConfigFormOptions {
  mapping?: YMapping;
  interception?: YInterception;
  version?: string | number;
  watch?: { [key: string]: any } | undefined;
  methods?: { [key: string]: Function };
  computed?: { [key: string]: () => any };
  components?: { [key: string]: any };
  props?: { [key: string]: any };
  global?: { [key: string]: any };
  dictionary?: YDictionary;
}

type YMethods = { [key: string]: Function };
export default class ConfigForm {
  createElement: Function;
  mapping: YMapping;
  interception: YInterception | undefined;
  version: string | number;
  watch: { [key: string]: any } | undefined;
  methods: { [key: string]: Function } | undefined;
  computed: { [key: string]: () => any } | undefined;
  components: { [key: string]: any } | undefined;
  props: { [key: string]: any } | undefined;
  name = 'YcConfigForm';
  global: { [key: string]: any } = {};
  allForm: { [key: string]: YForm } = {};
  dictionary: YDictionary = {};
  markRaw?: (component: any) => any;
  Vue: any = {};
  constructor(createElement: Function | any, options: YConfigFormOptions = {}) {
    this.Vue = typeof createElement === 'function' ? {} : createElement;
    this.createElement =
      typeof createElement === 'function' ? createElement : createElement.h;
    this.mapping = options.mapping || {};
    this.interception = options.interception;
    this.version = options.version || 2;
    this.methods = options.methods;
    this.watch = options.watch;
    this.computed = options.computed;
    this.components = options.components;
    this.props = options.props;
    this.global = options.global || {};
    this.dictionary = options.dictionary || {};
    return this;
  }

  get formMapping() {
    return this.mapping.formMapping || {};
  }

  setUI(UIName: YUIName, options: YOptions = {}) {
    this.markRaw = options.markRaw;
    const useConfig = getYcConfigFormOption(UIName, options);
    return this.use(useConfig);
  }

  ElementPlus(options: YOptions = {}) {
    return this.setUI('elementPlus', { ...options, version: 3 });
  }

  TDesign(options: YOptions = {}) {
    return this.setUI('tDesign', { ...options, version: 3 });
  }

  ArcoDesign(options: YOptions = {}) {
    return this.setUI('arcoDesign', { ...options, version: 3 });
  }

  AntDesign(options: YOptions = {}) {
    return this.setUI('antDesign', { ...options, version: 3 });
  }

  toMarkRaw(components: { [key: string]: any }) {
    if (this.markRaw) {
      const markRaw = this.markRaw;
      return Object.keys(components).reduce(
        (componentMap: { [key: string]: any }, componentName: string) => {
          componentMap[componentName] = markRaw(components[componentName]);
          return componentMap;
        },
        {}
      );
    }
    return components;
  }

  setMapping(mapping: YMapping = {}) {
    this.setComponentMapping(mapping.componentMapping);
    this.setDefaultRequiredRuleMapping(mapping.defaultRequiredRuleMapping);
    this.setDefaultValueMapping(mapping.defaultValueMapping);
    this.setFormMapping(mapping.formMapping);
    this.setEmitMapping(mapping.emitMapping);
    this.setPlaceholderMapping(mapping.placeholderMapping);
    this.setModelMapping(mapping.modelMapping);
    this.setUIFormMapping(mapping.UIFormMapping);
    return this;
  }

  setConfigOptions(options: YConfigFormOptions) {
    if (options.components) {
      this.setComponents(options.components);
    }
    if (options.mapping) {
      this.setMapping(options.mapping);
    }
    if (options.interception) {
      this.setInterception(options.interception);
    }
    if (options.computed) {
      this.computed = Object.assign({}, this.computed, options.computed);
    }
    if (options.methods) {
      this.methods = Object.assign({}, this.methods, options.methods);
    }
    if (options.version) {
      this.setVersion(options.version);
    }
    if (options.props) {
      this.setProps(options.props);
    }
    return this;
  }

  setComponents(components: { [key: string]: any }) {
    this.components = Object.assign({}, this.components, components);
    return this;
  }

  setComponentMapping(componentMapping: { [key: string]: any } = {}) {
    this.mapping.componentMapping = Object.assign(
      {},
      this.mapping.componentMapping,
      componentMapping
    );
    return this;
  }

  setEmitMapping(emitMapping: { [key: string]: string[] } = {}) {
    this.mapping.emitMapping = Object.assign(
      {},
      this.mapping.emitMapping,
      emitMapping
    );
    return this;
  }

  setModelMapping(modelMapping: { [key: string]: string } = {}) {
    this.mapping.modelMapping = Object.assign(
      {},
      this.mapping.modelMapping,
      modelMapping
    );
  }

  setUIFormMapping(UIFormMapping?: { form: string; props: string[] }) {
    this.mapping.UIFormMapping = Object.assign(
      {},
      this.mapping.UIFormMapping,
      UIFormMapping
    );
  }

  setDefaultRequiredRuleMapping(
    defaultRequiredRuleMapping: {
      [key: string]: (
        config: YItemConfig,
        message: string | string[]
      ) => YRule[];
    } = {}
  ) {
    this.mapping.defaultRequiredRuleMapping = Object.assign(
      {},
      this.mapping.defaultRequiredRuleMapping,
      defaultRequiredRuleMapping
    );
    return this;
  }

  setDefaultValueMapping(defaultValueMapping: { [key: string]: any } = {}) {
    this.mapping.defaultValueMapping = Object.assign(
      {},
      this.mapping.defaultValueMapping,
      defaultValueMapping
    );
    return this;
  }

  setFormMapping(formMapping: FormMapping = {}) {
    this.mapping.formMapping = Object.assign(
      {},
      this.mapping.formMapping,
      formMapping
    );
    return this;
  }

  setPlaceholderMapping(
    placeholderMapping: {
      [key: string]: (label: string) => string | string[];
    } = {}
  ) {
    this.mapping.placeholderMapping = Object.assign(
      {},
      this.mapping.placeholderMapping,
      placeholderMapping
    );
    return this;
  }

  setProps(props: { [key: string]: any } = {}) {
    this.props = Object.assign({}, this.props, props);
    return this;
  }

  setCreateElement(createElement: Function) {
    this.createElement = createElement;
    return this;
  }

  setInterception(interception: YInterception) {
    this.interception = this.interception || {};
    interception.event && (this.interception.event = interception.event);
    interception.get && (this.interception.get = interception.get);
    interception.itemConfig &&
      (this.interception.itemConfig = Object.assign(
        {},
        this.interception.itemConfig,
        interception.itemConfig
      ));
    interception.props &&
      typeof interception.props === 'function' &&
      (this.interception.props = interception.props);
    interception.rule && (this.interception.rule = interception.rule);
    interception.set && (this.interception.set = interception.set);
    interception.validate &&
      (this.interception.validate = interception.validate);
    interception.node && (this.interception.node = interception.node);

    return this;
  }

  get propsInterception() {
    const defaultHandler = (props: { [key: string]: any }, form: YForm) =>
      props;
    if (this.interception) {
      return this.interception.props ? this.interception.props : defaultHandler;
    }
    return defaultHandler;
  }

  setVersion(version?: string | number) {
    this.version = version || this.version;
    return this;
  }

  get isVue3() {
    return ~~this.version === 3;
  }

  use(
    options:
      | YMapping
      | YInterception
      | YConfigFormOptions
      | Function
      | { methods: YMethods }
      | { computed: YMethods }
  ) {
    const isObject = typeof options === 'object';
    if (isObject) {
      if ('methods' in options) {
        this.methods = Object.assign({}, this.methods, options.methods);
      }

      if ('computed' in options) {
        this.computed = Object.assign({}, this.computed, options.computed);
      }

      if ('dictionary' in options) {
        this.setDictionary(options.dictionary);
      }

      if ('watch' in options) {
        this.setWatch(options.watch);
      }

      this.setMapping(options as YMapping)
        .setInterception(options as YInterception)
        .setConfigOptions(options as YConfigFormOptions);

      if ('version' in options) {
        this.setVersion(options.version);
      }
    }
    return this;
  }

  setWatch(watch: { [key: string]: any } | undefined) {
    this.watch = Object.assign({}, this.watch, watch);
    return this;
  }

  setDictionary(dictionary: YDictionary = {}) {
    this.dictionary = Object.assign(this.dictionary, dictionary);
    return this;
  }

  setGlobal(key: string, value: any) {
    this.global[key] = value;
    return this;
  }

  setGlobalMap(data: { [key: string]: any }) {
    this.global = Object.assign({}, this.global, data);
  }

  getGlobal(key?: string) {
    return key ? this.global[key] : this.global;
  }

  resolveDirective(name: string) {
    if (name === 'show') {
      return this.Vue.vShow;
    }
    return this.Vue.resolveDirective
      ? this.Vue.resolveDirective(name)
      : undefined;
  }

  withDirectives(node: any, directives: Array<any> = []) {
    return this.Vue.withDirectives && directives.length
      ? this.Vue.withDirectives(node, directives)
      : node;
  }

  $end() {
    const isVue3 = this.isVue3;
    const version = this.version;
    const createElement = this.createElement;
    const mapping = this.mapping;
    const components = this.components;
    const interception = this.interception;
    const defaultValueMapping = this.mapping.defaultValueMapping || {};
    const formatGet = interception?.get;
    const formatSet = interception?.set;
    const allForm = this.allForm;
    const ConfigForm = this;
    return {
      name: this.name,
      inject: { formParent: { default: undefined } },
      props: Object.assign(
        {
          baseComponentName: { type: String, default: undefined },
          parentName: { type: String, default: undefined },
          name: { type: String, default: undefined },
          config: { type: Array, default: () => [] },
          rules: { type: Object, default: () => ({}) },
          scopedData: { type: Object, default: undefined },
          created: { type: Function, default: undefined },
          mounted: { type: Function, default: undefined },
          beforeDestroy: { type: Function, default: undefined },
          validate: { type: Function, default: undefined },
          interception: { type: Object, default: () => ({}) },
          firstNode: { type: Boolean, default: false },
        },
        this.props
      ),
      data(this: YForm) {
        const globalComponents = isVue3
          ? (this as any).$.appContext.components
          : {};
        return {
          scoped: {},
          rightConfig: {},
          localData: {},
          formData: {},
          identifier: 'YForm' + Math.round(Math.random() * 99999),
          newRules: {},
          formEntity: new Form([], this),
          createEntity: new CreateEntity(
            {
              form: this,
              createElement: isVue3
                ? createElement
                : createElement || this.$createElement,
              mapping,
              components: ConfigForm.toMarkRaw(
                Object.assign({}, globalComponents, components)
              ),
              version,
              interception,
            },
            ConfigForm
          ),
          formUtil: new FormUtil(undefined, this),
          dictionary: {},
        };
      },
      watch: Object.assign(
        {
          name(this: YForm, newValue: string, oldValue?: string) {
            if (oldValue) {
              delete allForm[oldValue];
            }
            if (newValue) {
              allForm[newValue] = this;
            }
          },
        },
        this.watch
      ),
      methods: Object.assign(
        {
          setComponents(this: YForm, components: { [key: string]: any }) {
            this.createEntity.setComponents(ConfigForm.toMarkRaw(components));
            return this;
          },
          getComponents(this: YForm) {
            return this.createEntity.getComponents();
          },
          getAllForm() {
            return allForm;
          },
          getFormByName(name: string) {
            return allForm[name];
          },
          setBind(
            this: YForm,
            prop: string | string[],
            key: string,
            value: any
          ) {
            this.formUtil.setBind(prop, key, value);
            return this.updateConfig();
          },
          setGlobal(this: YForm, key: string, value: any) {
            ConfigForm.setGlobal(key, value);
            return this;
          },
          setGlobalMap(this: YForm, data: { [key: string]: any }) {
            ConfigForm.setGlobalMap(data);
            return this;
          },
          getGlobal(this: YForm, key?: string) {
            return ConfigForm.getGlobal(key);
          },
          setScopedData(this: YForm, key: string, value: any) {
            this.scoped[key] = value;
            return this;
          },
          setScopedDataMap(this: YForm, data: { [key: string]: any }) {
            data = this.createEntity.deepClone(data);
            Object.keys(data).forEach((name) => {
              this.setScopedData(name, data[name]);
            });
            return this;
          },
          getScopedData(this: YForm, key?: string) {
            const data = this.createEntity.dataBump(this.scoped);
            return key ? data[key] : data;
          },
          setDictionary(this: YForm, dictionary: YDictionary) {
            this.dictionary = { ...this.dictionary, ...dictionary };
            return this;
          },
          getDictionary(this: YForm) {
            return { ...ConfigForm.dictionary, ...this.dictionary };
          },
          refresh(this: YForm) {
            this.scoped = this.createEntity.deepClone(this.scopedData || {});
            const rightConfig = this.firstNode
              ? this.config[0]
                ? [this.config[0]]
                : []
              : this.config;
            this.formUtil = new FormUtil(rightConfig, this);
            this.updateConfig(true);

            this.clearValidate();
            return this;
          },
          clearValidate(this: YForm, props?: string[]) {
            if ((this as any).$refs.form) {
              (this as any).$refs.form.clearValidate(props);
            }
            return this;
          },
          updateConfig(this: YForm, isReset?: boolean) {
            this.rightConfig = this.formUtil.getFormConfig(interception);
            const newRules = this.createEntity.getConfigRules(
              (this as any).$props.rules,
              this.formUtil.getItemConfigs()
            );
            if (!this.createEntity.isEqual(newRules, this.newRules)) {
              this.newRules = newRules;
            }
            this.updateFormData(isReset);
            return this;
          },
          updateFormData(this: YForm, isReset?: boolean) {
            this.formData = this.formUtil
              .getItemConfigs()
              .reduce(
                (data: { [key: string]: any }, itemConfig: YItemConfig) => {
                  const value = itemConfig.value;
                  const type = this.getConfigFileValue(itemConfig, 'type');
                  const prop = this.getConfigFileValue(itemConfig, 'prop');
                  if (prop) {
                    const defaultValue =
                      this.formData[prop] === undefined
                        ? defaultValueMapping[type] || undefined
                        : isReset
                        ? undefined
                        : this.formData[prop];
                    data[prop] = [null, undefined].includes(value)
                      ? defaultValue
                      : value;
                  }
                  return data;
                },
                {}
              );
            return this;
          },
          getConfigFileValue(
            this: YForm,
            itemConfig: YItemConfig,
            key: string
          ) {
            return this.createEntity.getConfigFile(itemConfig, key);
          },
          getFormData(this: YForm, isValidate?: boolean) {
            let params = Object.keys(this.formData).reduce(
              (data: { [key: string]: any }, prop: string) => {
                data[this.createEntity.toOriginPropName(prop)] =
                  this.formData[prop];
                return data;
              },
              {}
            );
            const configs: YItemConfig[] = this.formUtil.getItemConfigs();
            params = Object.keys(params).reduce(
              (obj: { [key: string]: any }, prop: string) => {
                const value = params[prop];
                const itemConfig = configs.find(
                  (config) => prop === this.getConfigFileValue(config, 'prop')
                );
                if (itemConfig) {
                  const isToFormData = this.getConfigFileValue(
                    itemConfig,
                    'toFormData'
                  );

                  obj[prop] = formatGet
                    ? formatGet(this, prop, value, itemConfig)
                    : value;
                  if ('toFormData' in itemConfig && !isToFormData) {
                    delete obj[prop];
                    return obj;
                  }
                  if (itemConfig.props) {
                    const rightProps = this.getConfigFileValue(
                      itemConfig,
                      'props'
                    );
                    if (rightProps && Array.isArray(rightProps)) {
                      rightProps.forEach((key: string, i: number) => {
                        obj[key] = (obj[prop] || [])[i];
                      });
                    }
                    const type = this.getConfigFileValue(itemConfig, 'type');
                    if (
                      this.createEntity
                        .toLine(prop)
                        .indexOf(this.createEntity.toLine(type)) === 0
                    ) {
                      delete obj[prop];
                    }
                  }
                } else {
                  obj[prop] = value;
                }
                return obj;
              },
              {}
            );
            params = this.createEntity.deepMerge(
              this.createEntity.dataBump(params),
              this.localData
            );
            if (isValidate) {
              return new Promise((resolve, reject) => {
                const form = (this as any).$refs.configForm;
                if (interception?.validate) {
                  interception.validate(form, (isValid: boolean) => {
                    return this.validate
                      ? this.validate(isValid, params, this)
                        ? resolve(true)
                        : reject(false)
                      : (isValid ? resolve : reject)(isValid);
                  });
                } else {
                  form.validate((isValid: boolean) =>
                    this.validate
                      ? this.validate(isValid, params, this)
                        ? resolve(true)
                        : reject(false)
                      : (isValid ? resolve : reject)(isValid)
                  );
                }
              })
                .then(() => params)
                .catch(() =>
                  this.validate
                    ? this.validate(false, params, this)
                      ? Promise.resolve(params)
                      : Promise.reject(false)
                    : Promise.reject(false)
                );
            }
            return params;
          },
          removeFormData(this: YForm, key: string) {
            delete this.formData[key];
            return this;
          },
          setFormData(
            this: YForm,
            key: string | { [key: string]: any },
            value: any = undefined,
            toLocal = true
          ) {
            if (typeof key !== 'string') {
              return this.setFormDataMap(key);
            }
            if (key in this.formData) {
              if (formatSet) {
                const config = this.getItemConfig(key);
                if (config) {
                  value = formatSet(this, key, value, config);
                }
              }
              this.formData[key] = value;
            } else if (toLocal) {
              this.localData[key] = value;
            } else {
              this.formData[key] = value;
            }
            return this;
          },
          setFormDataMap(
            this: YForm,
            data: { [key: string]: any },
            toLocal = true
          ) {
            Object.keys(data).forEach((key: string) => {
              Object.keys(this.formData).forEach((dataKey: string) => {
                if (key === dataKey) {
                  delete this.formData[key];
                } else if (
                  dataKey.indexOf(key + '[') === 0 ||
                  dataKey.indexOf(key + '.') === 0
                ) {
                  delete this.formData[dataKey];
                }
              });
            });
            data = this.createEntity.objToPath(data);
            this.formData = { ...this.formData, ...data };
            return this;
          },
          setDisabled(
            this: YForm,
            disabled: boolean,
            props?: string | string[]
          ) {
            this.formUtil.setDisabled(disabled, props);
            return this.updateConfig();
          },
          setRequired(
            this: YForm,
            required: boolean,
            props?: string | string[]
          ) {
            this.formUtil.setRequired(required, props);
            return this.updateConfig();
          },
          setOptions(
            this: YForm,
            prop: string,
            options: { [key: string]: any }[]
          ) {
            this.formUtil.setOptions(prop, options);
            return this.updateConfig();
          },
          setOptionsMap(
            this: YForm,
            options: { [key: string]: { [key: string]: any }[] }
          ) {
            this.formUtil.setOptionsMap(options);
            return this.updateConfig();
          },
          setConfig(this: YForm, prop: string, config: YItemConfig) {
            this.formUtil.setConfig(prop, config);
            return this;
          },
          removeConfig(this: YForm, props: string | string[]) {
            this.formUtil.removeConfig(props);
            return this.updateConfig();
          },
          appendConfigBefore(this: YForm, prop: string, config: YItemConfig) {
            this.formUtil.appendConfigBefore(prop, config);
            return this.updateConfig();
          },
          appendConfigAfter(this: YForm, prop: string, config: YItemConfig) {
            this.formUtil.appendConfigAfter(prop, config);
            return this.updateConfig();
          },
          replaceConfig(this: YForm, prop: string, config: YItemConfig) {
            this.formUtil.replaceConfig(prop, config);
            return this.updateConfig();
          },
          queryLikeItemConfig(
            this: YForm,
            key: string,
            value: string | number
          ) {
            const itemConfigs: YItemConfig[] = this.getItemConfigs();
            return itemConfigs.filter(
              (itemConfig) => (itemConfig[key] || '').indexOf(value + '') >= 0
            );
          },
          queryLikeRow(this: YForm, id: string | number) {
            const itemRows: YItemRow[] = this.getRows();
            return itemRows.filter(
              (itemRow) => (itemRow.id || '').indexOf(id + '') >= 0
            );
          },
          getRow(this: YForm, id: string | number) {
            const itemRows: YItemRow[] = this.getRows();
            return itemRows.find((itemRow) => itemRow.id === id);
          },
          getRows(this: YForm) {
            return this.formUtil.getRows();
          },
          removeRow(this: YForm, id: string | number) {
            this.formUtil.removeRow(id);
            return this.updateConfig();
          },
          appendRow(this: YForm, config: YItemConfig | YItemRow | YItemRow[]) {
            this.formUtil.appendRow(config);
            return this.updateConfig();
          },
          appendRowBefore(
            this: YForm,
            id: string | number,
            config: YItemConfig | YItemRow | YItemRow[]
          ) {
            this.formUtil.appendRowBefore(id, config);
            return this.updateConfig();
          },
          appendRowAfter(
            this: YForm,
            id: string | number,
            config: YItemConfig | YItemRow | YItemRow[]
          ) {
            this.formUtil.appendRowAfter(id, config);
            return this.updateConfig();
          },
          getItemConfig(this: YForm, prop: string) {
            return this.getItemConfigs().find(
              (config: YItemConfig) => config.prop === prop
            );
          },
          getItemConfigs(this: YForm) {
            return this.formUtil.getItemConfigs();
          },
          getEvents(this: YForm, prop: string) {
            return this.formUtil.getEvents(prop);
          },
          async trigger(
            this: YForm,
            prop: string,
            eventName: string,
            value: any,
            callBack?: Function
          ) {
            const itemConfig = this.getItemConfig(prop);
            if (itemConfig) {
              const events = itemConfig.events || [];
              const eventInfos = events.filter(
                (eventItem: YEvent) => eventItem.name === eventName
              );
              for (const eventInfo of eventInfos) {
                if (eventInfo) {
                  if (eventInfo) {
                    const handler =
                      eventInfo.handler ||
                      (eventInfo.method &&
                        this.formParent &&
                        this.formParent[eventInfo.method]);
                    if (handler) {
                      const ref = this.getConfigFileValue(itemConfig, 'ref');
                      const data = {
                        value:
                          value === undefined ? value : this.formData[prop],
                        formData: this.formData,
                        ref: ref ? (this as any).$refs[ref] : undefined,
                        form: this,
                        args: [],
                        config: itemConfig,
                        prop,
                      };
                      const handlerResult = handler(data);
                      const isPromise =
                        this.createEntity.isPromise(handlerResult);
                      const result = isPromise
                        ? await handlerResult
                        : handlerResult;
                      callBack && callBack(result);
                    }
                  }
                }
              }
            }
          },
          isPromise(this: YForm, fn: any) {
            return this.createEntity.isPromise(fn);
          },
          getParentMethod(this: YForm, eventName: string) {
            const $parent = this.getParent();
            if ($parent) {
              return $parent[eventName];
            }
            return undefined;
          },
          triggerParent(this: YForm, eventName: string, ...args: any) {
            const method = this.getParentMethod(eventName);
            if (method) {
              method(...args);
            }
            return this;
          },
          getRef(this: YForm, refName: string) {
            return this.getRefs()[refName];
          },
          getRefs(this: YForm) {
            return (this as any).$refs || {};
          },
          getOriginRef(this: YForm) {
            return this.getRef('configForm');
          },
          triggerRef(
            this: YForm,
            refName: string,
            eventName: string,
            ...args: any
          ) {
            const refNode = this.getRef(refName);
            if (refNode && !Array.isArray(refNode)) {
              const method = refNode[eventName];
              if (method && typeof method === 'function') {
                method(...args);
              }
            }
            return this;
          },
          getParent(this: YForm) {
            const parentName = this.parentName;
            if (!parentName) {
              return undefined;
            }
            let node: any = this;
            while (node.$options.name !== parentName) {
              node = node.$parent;
              if (!node) {
                break;
              }
            }
            if (!node) {
              return undefined;
            }
            return node;
          },
        },
        this.methods
      ),
      beforeCreate(this: YForm) {
        if (this.beforeCreate) {
          this.beforeCreate(this);
        }
      },
      created(this: YForm) {
        this.refresh();
        if (this.name) {
          allForm[this.name] = this;
        }
        if (this.created) {
          this.created(this);
        }
      },
      mounted(this: YForm) {
        if (this.mounted) {
          this.mounted(this);
        }
      },
      [isVue3 ? 'beforeUnmount' : 'beforeDestroy'](this: YForm) {
        if (this.name) {
          delete allForm[this.name];
        }
        if (this.beforeDestroy) {
          this.beforeDestroy(this);
        }
      },
      render(this: YForm) {
        return this.createEntity.init(this.rightConfig, this.baseComponentName);
      },
    };
  }
}
